package com.zeratul.web.validate.utils;

import cn.hutool.core.util.ObjectUtil;
import com.zeratul.common.core.exception.ServiceException;
import com.zeratul.common.core.result.codes.ResultCodes;
import com.zeratul.common.core.utils.spring.SpringUtils;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 手动校验处理器
 */
public class ZtValidUtils {

    /**
     * 校验处理器
     */
    private static Validator validator;

    static {
        validator = SpringUtils.getBean(Validator.class);
    }

    /**
     * 校验不允许对象为空
     */
    public static <T> void validate(T obj, Class<?>...groupCls) {
        validate(obj, false, groupCls);
    }

    /**
     * 核心校验方法
     * @param obj
     * @param <T>
     */
    public static <T> void validate(T obj, boolean nullable, Class<?>...groupCls) {
        //判断校验对象是否为空
        if (ObjectUtil.isNull(obj)) {
            //判断是否允许校验对象为空，如果允许则直接返回，不允许则直接报错
            if (nullable) {
                return;
            } else {
                throw new ServiceException(ResultCodes.VALIDATE_OBJ_NOT_NULL);
            }
        }

        //执行参数校验
        Set<ConstraintViolation<T>> validateResults = validator.validate(obj, groupCls);
        if (ObjectUtil.isEmpty(validateResults)) {
            //如果校验通过，则直接返回
            return;
        }

        //存放异常信息的Map
        Map<String, String> resultMap = new HashMap<>();
        for (ConstraintViolation<T> violation : validateResults) {
            String field = violation.getPropertyPath().toString();
            if (ObjectUtil.isEmpty(field)) {
                field = violation.getRootBeanClass().getSimpleName().toLowerCase();
            }
            String message = violation.getMessage();
            resultMap.put(field, message);
        }
        throw new ServiceException(ResultCodes.PARAM_ERROR, resultMap);
    }
}
